using System;
using System.Configuration;

namespace NWrapper.Config
{
	/// <summary>
	/// Represents the settings for a given cache implementation.
	/// </summary>
	public class CacheSettings : ConfigurationElement
	{
		private static readonly CacheSettings _defaultConfiguration = new CacheSettings(CacheType.None);

		/// <summary>
		/// Default constructor, uses <see cref="CacheType.None"/>.
		/// </summary>
		public CacheSettings()
			: this(CacheType.None)
		{
		}

		/// <summary>
		/// Sets the cache configuration to use the given cache type.
		/// </summary>
		/// <param name="type">The cache type.</param>
		public CacheSettings(CacheType type)
			: base()
		{
			this.Type = type;
		}

        /// <summary>
        /// Sets the cache configuration to use a custom cache identified by the given
        /// assembly and class.
        /// </summary>
        /// <param name="assemblyName">Name of the assembly.</param>
        /// <param name="className">Name of the class.</param>
		public CacheSettings(string assemblyName, string className)
			: base()
		{
			this.Type = CacheType.Custom;
			this.Assembly = assemblyName;
			this.Class = className;
		}

		/// <summary>
		/// Returns a default instance of this class, using <see cref="CacheType.None"/>.
		/// </summary>
		public static CacheSettings Default
		{
			get { return _defaultConfiguration; }
		}

		/// <summary>
		/// Gets or sets the cache type.
		/// </summary>
		[ConfigurationProperty("type", IsRequired = true)]
		public CacheType Type
		{
			get { return (CacheType)(base["type"]); }
			set { base["type"] = value; }
		}

		/// <summary>
		/// Gets or sets the name of the assembly. Should be used when you are using
		/// <see cref="CacheType.Custom"/>.
		/// </summary>
		[ConfigurationProperty("assembly")]
		public string Assembly
		{
			get
			{
				object asm = base["assembly"];
				if (asm == null)
					return String.Empty;
				else
					return asm.ToString();
			}
			set { base["assembly"] = value; }
		}

		/// <summary>
		/// Gets or sets the name of the class that implements this cache. 
		/// This class must implement <see cref="ICache"/>.
		/// Should be used when you are using <see cref="CacheType.Custom"/>.
		/// </summary>
		[ConfigurationProperty("class")]
		public string Class
		{
			get
			{
				object cls = base["class"];
				if (cls == null)
					return String.Empty;
				else
					return cls.ToString();
			}
			set { base["class"] = value; }
		}

		/// <summary>
		/// A set of key/value pairs that are exposed to the underlying repository and
		/// permit custom configuration commands to be passed to the repository.
		/// </summary>
		[ConfigurationProperty("custom")]
		public KeyValueConfigurationCollection Custom
		{
			get { return (KeyValueConfigurationCollection)base["custom"]; }
			set { base["custom"] = value; }
		}
	}
}
